<!DOCTYPE html><html lang="en" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>Zookeper | Hexo</title><meta name="author" content="John Doe"><meta name="copyright" content="John Doe"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Maven 依赖树的解析规则1. 依赖树结构​	在 pom.xml 的 dependencies 中声明依赖包后，Maven 将直接引入依赖，并通过解析直接依赖的 pom.xml 将传递性依赖导入到当前项目，最终形成一个树状的依赖结构。 原则：深度优先遍历依赖，并缓存节点剪枝。比如下图：  A→B→D→E&#x2F;F A→C→D  在第二步A→C→D 时，由于节点D已经被缓存，所以会立即返回，不">
<meta property="og:type" content="article">
<meta property="og:title" content="Zookeper">
<meta property="og:url" content="https://z-w-t.gitee.io/2023/10/23/Maven%20%E4%BE%9D%E8%B5%96%E6%A0%91%E7%9A%84%E8%A7%A3%E6%9E%90%E8%A7%84%E5%88%99/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="Maven 依赖树的解析规则1. 依赖树结构​	在 pom.xml 的 dependencies 中声明依赖包后，Maven 将直接引入依赖，并通过解析直接依赖的 pom.xml 将传递性依赖导入到当前项目，最终形成一个树状的依赖结构。 原则：深度优先遍历依赖，并缓存节点剪枝。比如下图：  A→B→D→E&#x2F;F A→C→D  在第二步A→C→D 时，由于节点D已经被缓存，所以会立即返回，不">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png">
<meta property="article:published_time" content="2023-10-23T10:00:27.020Z">
<meta property="article:modified_time" content="2023-10-25T12:13:59.425Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png"><link rel="shortcut icon" href="/zwt-life/img/favicon.png"><link rel="canonical" href="https://z-w-t.gitee.io/2023/10/23/Maven%20%E4%BE%9D%E8%B5%96%E6%A0%91%E7%9A%84%E8%A7%A3%E6%9E%90%E8%A7%84%E5%88%99/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/zwt-life/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
  root: '/zwt-life/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: 'Copy Successful',
    error: 'Copy Error',
    noSupport: 'Browser Not Supported'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: 'Just now',
    min: 'minutes ago',
    hour: 'hours ago',
    day: 'days ago',
    month: 'months ago'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  infinitegrid: {
    js: 'https://cdn.jsdelivr.net/npm/@egjs/infinitegrid/dist/infinitegrid.min.js',
    buttonText: 'Load More'
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Zookeper',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-10-25 20:13:59'
}</script><script>(win=>{
      win.saveToLocal = {
        set: (key, value, ttl) => {
          if (ttl === 0) return
          const now = Date.now()
          const expiry = now + ttl * 86400000
          const item = {
            value,
            expiry
          }
          localStorage.setItem(key, JSON.stringify(item))
        },
      
        get: key => {
          const itemStr = localStorage.getItem(key)
      
          if (!itemStr) {
            return undefined
          }
          const item = JSON.parse(itemStr)
          const now = Date.now()
      
          if (now > item.expiry) {
            localStorage.removeItem(key)
            return undefined
          }
          return item.value
        }
      }
    
      win.getScript = (url, attr = {}) => new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.src = url
        script.async = true
        script.onerror = reject
        script.onload = script.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          script.onload = script.onreadystatechange = null
          resolve()
        }

        Object.keys(attr).forEach(key => {
          script.setAttribute(key, attr[key])
        })

        document.head.appendChild(script)
      })
    
      win.getCSS = (url, id = false) => new Promise((resolve, reject) => {
        const link = document.createElement('link')
        link.rel = 'stylesheet'
        link.href = url
        if (id) link.id = id
        link.onerror = reject
        link.onload = link.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          link.onload = link.onreadystatechange = null
          resolve()
        }
        document.head.appendChild(link)
      })
    
      win.activateDarkMode = () => {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = () => {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
        if (t === 'dark') activateDarkMode()
        else if (t === 'light') activateLightMode()
      
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
      const detectApple = () => {
        if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
          document.documentElement.classList.add('apple')
        }
      }
      detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/zwt-life/archives/"><div class="headline">Articles</div><div class="length-num">6</div></a><a href="/zwt-life/tags/"><div class="headline">Tags</div><div class="length-num">0</div></a><a href="/zwt-life/categories/"><div class="headline">Categories</div><div class="length-num">0</div></a></div><hr class="custom-hr"/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/zwt-life/"><i class="fa-fw fas fa-home"></i><span> 首頁</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fa fa-heartbeat"></i><span> 清单</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/zwt-life/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/zwt-life/Gallery/"><i class="fa-fw fas fa-images"></i><span> 照片</span></a></li><li><a class="site-page child" href="/zwt-life/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/zwt-life/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header"><nav id="nav"><span id="blog-info"><a href="/zwt-life/" title="Hexo"><span class="site-name">Hexo</span></a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/zwt-life/"><i class="fa-fw fas fa-home"></i><span> 首頁</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fa fa-heartbeat"></i><span> 清单</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/zwt-life/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/zwt-life/Gallery/"><i class="fa-fw fas fa-images"></i><span> 照片</span></a></li><li><a class="site-page child" href="/zwt-life/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/zwt-life/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/zwt-life/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Zookeper</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">Created</span><time class="post-meta-date-created" datetime="2023-10-23T10:00:27.020Z" title="Created 2023-10-23 18:00:27">2023-10-23</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2023-10-25T12:13:59.425Z" title="Updated 2023-10-25 20:13:59">2023-10-25</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Zookeper"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">Post Views:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="Maven-依赖树的解析规则"><a href="#Maven-依赖树的解析规则" class="headerlink" title="Maven 依赖树的解析规则"></a>Maven 依赖树的解析规则</h1><h2 id="1-依赖树结构"><a href="#1-依赖树结构" class="headerlink" title="1. 依赖树结构"></a>1. 依赖树结构</h2><p>​	在 pom.xml 的 dependencies 中声明依赖包后，Maven 将直接引入依赖，并通过解析直接依赖的 pom.xml 将传递性依赖导入到当前项目，最终形成一个树状的依赖结构。</p>
<p><strong>原则：深度优先遍历依赖，并缓存节点剪枝。比如下图：</strong></p>
<ul>
<li><strong>A→B→D→E&#x2F;F</strong></li>
<li><strong>A→C→D</strong></li>
</ul>
<p>在第二步A→C→D 时，由于节点D已经被缓存，所以会立即返回，不必再次遍历E&#x2F;F，避免重复搜索。</p>
<h2 id="2-依赖冲突"><a href="#2-依赖冲突" class="headerlink" title="2. 依赖冲突"></a>2. 依赖冲突</h2><h3 id="Maven的版本依赖冲突后的优先顺序"><a href="#Maven的版本依赖冲突后的优先顺序" class="headerlink" title="Maven的版本依赖冲突后的优先顺序"></a>Maven的版本依赖冲突后的优先顺序</h3><ol>
<li>直接在当前工程中显示指定的版本   （当前项目pom 文件中的 </dependencies>标签）</li>
<li><code>&lt;parent/&gt;</code>中配置的父工程使用的版本   （父项目pom 文件中的 </dependencies>标签）</li>
<li>在当前工程中通过<code>&lt;dependencyManagement/&gt;</code>引入的BOM清单中的版本，当引入的多个BOM都有对应jar包时，先引入的BOM生效</li>
<li>在父工程中通过<code>&lt;dependencyManagement/&gt;</code>引入的BOM清单中的版本，当引入的多个BOM都有对应jar包时，先引入的BOM生效</li>
<li>上述四个地方都没配置，则启用依赖调解机制</li>
</ol>
<h3 id="Maven的依赖调解机制"><a href="#Maven的依赖调解机制" class="headerlink" title="Maven的依赖调解机制"></a>Maven的依赖调解机制</h3><ol>
<li>路径最近者优先</li>
</ol>
<p>相同jar不同版本，根据依赖的路径长短来决定引入哪个依赖。</p>
<p>举例</p>
<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">依赖链路一：A <span class="punctuation">-&gt;</span> B <span class="punctuation">-&gt;</span> C <span class="punctuation">-&gt;</span> <span class="title function_ invoke__">X</span>(<span class="number">1.0</span>)</span><br><span class="line">依赖链路二：F <span class="punctuation">-&gt;</span> D <span class="punctuation">-&gt;</span> <span class="title function_ invoke__">X</span>(<span class="number">2.0</span>)</span><br></pre></td></tr></table></figure>

<p>该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。依赖调解第一原则不能解决所有问题，比如这样的依赖关系：</p>
<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">A <span class="punctuation">-&gt;</span> B <span class="punctuation">-&gt;</span> <span class="title function_ invoke__">Y</span>(<span class="number">1.0</span>)</span><br><span class="line">c <span class="punctuation">-&gt;</span> D <span class="punctuation">-&gt;</span> <span class="title function_ invoke__">Y</span>(<span class="number">2.0</span>)</span><br></pre></td></tr></table></figure>

<p>Y(1.0)和Y(2.0)的依赖路径长度是一样的，都为2。Maven定义了依赖调解的第二原则：</p>
<ol start="2">
<li>第一声明者优先</li>
</ol>
<p>在依赖路径长度相等的前提下，在POM中依赖声明的顺序决定了谁会被解析使用，顺序最前的那个依赖优胜。该例中，如果A的依赖声明在C之前，那么Y (1.0)就会被解析使用.</p>
<p><code>注意</code> 子pom内声明的优先于父pom中的依赖。</p>
<h3 id="统一依赖导致的问题"><a href="#统一依赖导致的问题" class="headerlink" title="统一依赖导致的问题"></a>统一依赖导致的问题</h3><p>1、你想如果A 引用E 2.0的新创建的类，但因为最终被解析的是 1.0 ，所以就会出现很典型的<code>NoClassDefFoundError</code> 或<code>ClassNotFoundException</code>依赖冲突报错。</p>
<p>2、如果A引用E 2.0的新创建的方法，但因为最终被解析的是1.0，所以就会抛出 <code>NoSuchMethodError</code>系统异常。</p>
<h2 id="3-依赖循环"><a href="#3-依赖循环" class="headerlink" title="3. 依赖循环"></a>3. 依赖循环</h2><p>​	比如：A 依赖了 B，同时 B 又依赖了 A。这种循环依赖可能不会直接显现，但是可能会在一个很长的调用关系显现出来，也可能是模块架构的设计不合理</p>
<p>​	我们可以使用** <strong>mvn dependency:tree -Dverbose | grep cycle</strong> **来判断项目中是否存在「循环依赖」。</p>
<h2 id="4-依赖排除"><a href="#4-依赖排除" class="headerlink" title="4. 依赖排除"></a>4. 依赖排除</h2><p>​	我们可以使用** <strong>exclusion</strong> <strong>来解决依赖冲突，但是</strong> <strong>exclusion</strong> **会降低 Maven 依赖解析的效率，因为对应的 pom 文件不能缓存，每次都要重新遍历子树。</p>
<p><strong>对于依赖排除：</strong></p>
<ul>
<li>exclusion** **会造成依赖重复扫描和缓存。</li>
<li>在距离根节点越远的** *<em>exclusion</em>***，影响的范围越小。</li>
<li>依赖树高度越高，引入** <strong>exclusion</strong> **的代价越大。</li>
</ul>
<h2 id="5-依赖分析IDEA-插件"><a href="#5-依赖分析IDEA-插件" class="headerlink" title="5. 依赖分析IDEA 插件"></a>5. 依赖分析IDEA 插件</h2><h2 id=""><a href="#" class="headerlink" title="**"></a><img src="https://docs.corp.kuaishou.com/image/api/external/load/out?code=fcAAw30eAsuAIFZAlCpbWFH29:772246374631178989fcAAw30eAsuAIFZAlCpbWFH29:1698056571033" alt="img">**</h2><p><strong>使用 IDEA 的话，可以在对应项目中右击，选择 Diagrams -&gt; Show Dependencies。</strong></p>
<p><strong><img src="https://docs.corp.kuaishou.com/image/api/external/load/out?code=fcAAw30eAsuAIFZAlCpbWFH29:8800690327421669248fcAAw30eAsuAIFZAlCpbWFH29:1698056571033" alt="img"></strong></p>
<h2 id="6-Maven-命令行"><a href="#6-Maven-命令行" class="headerlink" title="6. Maven 命令行"></a>6. Maven 命令行</h2><p>​		mvn dependency:tree -Dverbose</p>
<h2 id="7-番外"><a href="#7-番外" class="headerlink" title="7. 番外"></a>7. 番外</h2><h3 id="关于Maven-scope依赖范围"><a href="#关于Maven-scope依赖范围" class="headerlink" title="关于Maven scope依赖范围"></a>关于Maven scope依赖范围</h3><p> 　Maven的生命周期存在编译、测试、运行这些过程,那么显然有些依赖只用于测试，比如junit；有些依赖编译用不到，只有运行的时候才能用到，比如mysql的驱动包在编译期就用不到（编译期用的是JDBC接口），而是在运行时用到的；还有些依赖，编译期要用到，而运行期不需要提供，因为有些容器已经提供了，比如servlet-api在tomcat中已经提供了，我们只需要的是编译期提供而已。总结说来，在POM 4中，<dependency>中还引入了<scope>，它主要管理依赖的部署。大致有compile、provided、runtime、test、system等几个。</p>
<ol>
<li>compile：默认的scope，运行期有效，需要打入包中</li>
<li>provided：编译期有效，运行期不需要提供，不会打入包中</li>
<li>runtime：编译不需要，在运行期有效，需要导入包中。（接口与实现分离）</li>
<li>test：测试需要，不会打入包中</li>
<li>system：非本地仓库引入、存在系统的某个路径下的jar。（一般不使用）</li>
</ol>
<h3 id="关于fat-jar"><a href="#关于fat-jar" class="headerlink" title="关于fat jar"></a>关于fat jar</h3><h4 id="什么是-FatJar"><a href="#什么是-FatJar" class="headerlink" title="什么是 FatJar"></a>什么是 FatJar</h4><p>​		FatJar 又称作 uber-Jar，是包含所有依赖的 Jar 包。Jar 包中嵌入了除 java 虚拟机以外的所有依赖。我们知道 Java 的依赖分为两种， 零散的 .class 文件和把多个 .class 文件以 zip 格式打包而成 jar 文件。FatJar 是一个 all-in-one Jar 包。FatJar 技术可以让那些用于最终发布的 Jar 便于部署和运行。</p>
<p>​		不管你 dependences 里的 scope 设置为什么, mvn package 和 mvn install 出来的 jar 包只会包含自己的 src 的 classes. 即使你是 compile 的依赖, 也不会进去, 但是如果打成 war 包, 是会包含 compile scope 的依赖的. 而 provided 是要容器提供, 比如说 Tomcat, 会到 Tomcat 的 <code>$liferay-tomcat-home\webapps\ROOT\WEB-INF\lib</code> 目录下找. 而且 compile 的依赖是传递的, provided 的不传递.</p>
<p>​		可以通过 assembly&#x2F;shade 插件把依赖的 jar 包打到一个 assembly.jar 包中去. 和源码的 jar 包可以是独立的, 也可以打到一起. 如果你一个依赖(D1)有两个版本(在父&#x2F;子pom 中都有定义, 但是版本不一样), 在打出的 jar 包里只会有一个版本, 因为路径里不带版本的. 所以会出现各种 NoSuchMethodError 等等问题, 因为编译的时候都是各自用的正确的 D1 编译的出的 class. 但是运行时用到的 D1 只会有一个版本, 会有不匹配.</p>
<h3 id="关于BOM"><a href="#关于BOM" class="headerlink" title="关于BOM"></a>关于BOM</h3><h4 id="BOM是什么"><a href="#BOM是什么" class="headerlink" title="BOM是什么"></a>BOM是什么</h4><p>​	BOM全称Bill Of Materials，中文是材料清单。POM自身只支持单继承，BOM的作用就行进行统一的包版本管理。尤其适合解决对于微服务架构下，需要统一多个服务jar包版本的诉求。</p>
<p>开源的RPC组件Dubbo就提供了这样一份BOM：<a target="_blank" rel="noopener" href="https://github.com/apache/dubbo/tree/3.1/dubbo-dependencies-bom">dubbo-dependencies-bom</a></p>
<h4 id="BOM有什么"><a href="#BOM有什么" class="headerlink" title="BOM有什么"></a>BOM有什么</h4><p>​	BOM并不是特殊的技术或者组件，其仅仅是一份pom文件，核心是在<code>&lt;dependencyManagement/&gt;</code>节点中添加不同jar包的maven坐标。其他项目使用bom后，再引用bom中包含的jar时，就不需要显示的指定jar包版本了。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">&lt;project...&gt;	</span><br><span class="line">    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;</span><br><span class="line">    &lt;groupId&gt;com.jd.open&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;open-bom&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;</span><br><span class="line">    &lt;packaging&gt;pom&lt;/packaging&gt;</span><br><span class="line">    &lt;description&gt;parent pom&lt;/description&gt;</span><br><span class="line">    &lt;dependencyManagement&gt;</span><br><span class="line">        &lt;dependencies&gt;</span><br><span class="line">            &lt;dependency&gt;</span><br><span class="line">                &lt;groupId&gt;test&lt;/groupId&gt;</span><br><span class="line">                &lt;artifactId&gt;a&lt;/artifactId&gt;</span><br><span class="line">                &lt;version&gt;1.2&lt;/version&gt;</span><br><span class="line">            &lt;/dependency&gt;</span><br><span class="line">            &lt;dependency&gt;</span><br><span class="line">                &lt;groupId&gt;test&lt;/groupId&gt;</span><br><span class="line">                &lt;artifactId&gt;b&lt;/artifactId&gt;</span><br><span class="line">                &lt;version&gt;1.0&lt;/version&gt;</span><br><span class="line">                &lt;scope&gt;compile&lt;/scope&gt;</span><br><span class="line">            &lt;/dependency&gt;</span><br><span class="line">            &lt;dependency&gt;</span><br><span class="line">                &lt;groupId&gt;test&lt;/groupId&gt;</span><br><span class="line">                &lt;artifactId&gt;c&lt;/artifactId&gt;</span><br><span class="line">                &lt;version&gt;1.0&lt;/version&gt;</span><br><span class="line">                &lt;scope&gt;compile&lt;/scope&gt;</span><br><span class="line">            &lt;/dependency&gt;</span><br><span class="line">        &lt;/dependencies&gt;</span><br><span class="line">    &lt;/dependencyManagement&gt;</span><br><span class="line">&lt;/project&gt;</span><br></pre></td></tr></table></figure>

<h4 id="BOM的引用"><a href="#BOM的引用" class="headerlink" title="BOM的引用"></a>BOM的引用</h4><p>BOM使用有两种方式，可以通过<code>&lt;parent/&gt;</code>节点继承：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;project ...&gt;</span><br><span class="line">    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;</span><br><span class="line">    &lt;groupId&gt;com.jd&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;Test&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;</span><br><span class="line">    &lt;packaging&gt;pom&lt;/packaging&gt;</span><br><span class="line">    &lt;parent&gt;</span><br><span class="line">        &lt;groupId&gt;com.jd.open&lt;/groupId&gt;</span><br><span class="line">        &lt;artifactId&gt;open-bom&lt;/artifactId&gt;</span><br><span class="line">        &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;</span><br><span class="line">    &lt;/parent&gt;</span><br><span class="line">&lt;/project&gt;</span><br></pre></td></tr></table></figure>

<p>也可以在<code>&lt;dependencyManagement/&gt;</code>中引用</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">&lt;project ...&gt;</span><br><span class="line">    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;</span><br><span class="line">    &lt;groupId&gt;com.jd&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;Test&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;</span><br><span class="line">    &lt;packaging&gt;pom&lt;/packaging&gt;</span><br><span class="line">    &lt;dependencyManagement&gt;</span><br><span class="line">        &lt;dependencies&gt;</span><br><span class="line">            &lt;dependency&gt;</span><br><span class="line">                &lt;groupId&gt;com.jd.open&lt;/groupId&gt;</span><br><span class="line">                &lt;artifactId&gt;open-bom&lt;/artifactId&gt;</span><br><span class="line">                &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;</span><br><span class="line">                &lt;type&gt;pom&lt;/type&gt;</span><br><span class="line">                &lt;scope&gt;import&lt;/scope&gt;</span><br><span class="line">            &lt;/dependency&gt;</span><br><span class="line">        &lt;/dependencies&gt;</span><br><span class="line">    &lt;/dependencyManagement&gt;</span><br><span class="line">&lt;/project&gt;</span><br></pre></td></tr></table></figure>

<h2 id="-1"><a href="#-1" class="headerlink" title=""></a></h2></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>Author: </span><span class="post-copyright-info"><a href="https://z-w-t.gitee.io">John Doe</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>Link: </span><span class="post-copyright-info"><a href="https://z-w-t.gitee.io/2023/10/23/Maven%20%E4%BE%9D%E8%B5%96%E6%A0%91%E7%9A%84%E8%A7%A3%E6%9E%90%E8%A7%84%E5%88%99/">https://z-w-t.gitee.io/2023/10/23/Maven%20%E4%BE%9D%E8%B5%96%E6%A0%91%E7%9A%84%E8%A7%A3%E6%9E%90%E8%A7%84%E5%88%99/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>Copyright Notice: </span><span class="post-copyright-info">All articles in this blog are licensed under <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> unless stating additionally.</span></div></div><div class="tag_share"><div class="post-meta__tag-list"></div><div class="post_share"><div class="social-share" data-image="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-full"><a href="/zwt-life/2023/10/23/%E7%BC%93%E5%AD%98%E7%9A%84%E5%A5%A5%E4%B9%89/" title="缓存"><div class="cover" style="background: var(--default-bg-color)"></div><div class="pagination-info"><div class="label">Previous</div><div class="prev_info">缓存</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png" onerror="this.onerror=null;this.src='/zwt-life/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">John Doe</div><div class="author-info__description"></div></div><div class="card-info-data site-data is-center"><a href="/zwt-life/archives/"><div class="headline">Articles</div><div class="length-num">6</div></a><a href="/zwt-life/tags/"><div class="headline">Tags</div><div class="length-num">0</div></a><a href="/zwt-life/categories/"><div class="headline">Categories</div><div class="length-num">0</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/xxxxxx"><i class="fab fa-github"></i><span>Follow Me</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>Announcement</span></div><div class="announcement_content">This is my Blog</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>Contents</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Maven-%E4%BE%9D%E8%B5%96%E6%A0%91%E7%9A%84%E8%A7%A3%E6%9E%90%E8%A7%84%E5%88%99"><span class="toc-number">1.</span> <span class="toc-text">Maven 依赖树的解析规则</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E4%BE%9D%E8%B5%96%E6%A0%91%E7%BB%93%E6%9E%84"><span class="toc-number">1.1.</span> <span class="toc-text">1. 依赖树结构</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E4%BE%9D%E8%B5%96%E5%86%B2%E7%AA%81"><span class="toc-number">1.2.</span> <span class="toc-text">2. 依赖冲突</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Maven%E7%9A%84%E7%89%88%E6%9C%AC%E4%BE%9D%E8%B5%96%E5%86%B2%E7%AA%81%E5%90%8E%E7%9A%84%E4%BC%98%E5%85%88%E9%A1%BA%E5%BA%8F"><span class="toc-number">1.2.1.</span> <span class="toc-text">Maven的版本依赖冲突后的优先顺序</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Maven%E7%9A%84%E4%BE%9D%E8%B5%96%E8%B0%83%E8%A7%A3%E6%9C%BA%E5%88%B6"><span class="toc-number">1.2.2.</span> <span class="toc-text">Maven的依赖调解机制</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%9F%E4%B8%80%E4%BE%9D%E8%B5%96%E5%AF%BC%E8%87%B4%E7%9A%84%E9%97%AE%E9%A2%98"><span class="toc-number">1.2.3.</span> <span class="toc-text">统一依赖导致的问题</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-%E4%BE%9D%E8%B5%96%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.3.</span> <span class="toc-text">3. 依赖循环</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-%E4%BE%9D%E8%B5%96%E6%8E%92%E9%99%A4"><span class="toc-number">1.4.</span> <span class="toc-text">4. 依赖排除</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-%E4%BE%9D%E8%B5%96%E5%88%86%E6%9E%90IDEA-%E6%8F%92%E4%BB%B6"><span class="toc-number">1.5.</span> <span class="toc-text">5. 依赖分析IDEA 插件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link"><span class="toc-number">1.6.</span> <span class="toc-text">**</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6-Maven-%E5%91%BD%E4%BB%A4%E8%A1%8C"><span class="toc-number">1.7.</span> <span class="toc-text">6. Maven 命令行</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7-%E7%95%AA%E5%A4%96"><span class="toc-number">1.8.</span> <span class="toc-text">7. 番外</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8EMaven-scope%E4%BE%9D%E8%B5%96%E8%8C%83%E5%9B%B4"><span class="toc-number">1.8.1.</span> <span class="toc-text">关于Maven scope依赖范围</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8Efat-jar"><span class="toc-number">1.8.2.</span> <span class="toc-text">关于fat jar</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-FatJar"><span class="toc-number">1.8.2.1.</span> <span class="toc-text">什么是 FatJar</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8EBOM"><span class="toc-number">1.8.3.</span> <span class="toc-text">关于BOM</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#BOM%E6%98%AF%E4%BB%80%E4%B9%88"><span class="toc-number">1.8.3.1.</span> <span class="toc-text">BOM是什么</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#BOM%E6%9C%89%E4%BB%80%E4%B9%88"><span class="toc-number">1.8.3.2.</span> <span class="toc-text">BOM有什么</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#BOM%E7%9A%84%E5%BC%95%E7%94%A8"><span class="toc-number">1.8.3.3.</span> <span class="toc-text">BOM的引用</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#-1"><span class="toc-number">1.9.</span> <span class="toc-text"></span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>Recent Post</span></div><div class="aside-list"><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/zwt-life/2023/10/25/todo/" title="todo">todo</a><time datetime="2023-10-25T07:14:45.519Z" title="Created 2023-10-25 15:14:45">2023-10-25</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/zwt-life/2023/10/25/Zookeper/" title="Zookeper">Zookeper</a><time datetime="2023-10-25T03:19:39.229Z" title="Created 2023-10-25 11:19:39">2023-10-25</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/zwt-life/2023/10/24/gitee%20blog/" title="Gitee blog">Gitee blog</a><time datetime="2023-10-24T03:25:27.640Z" title="Created 2023-10-24 11:25:27">2023-10-24</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/zwt-life/2023/10/24/hello-world/" title="Hello World">Hello World</a><time datetime="2023-10-24T03:09:38.044Z" title="Created 2023-10-24 11:09:38">2023-10-24</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/zwt-life/2023/10/23/%E7%BC%93%E5%AD%98%E7%9A%84%E5%A5%A5%E4%B9%89/" title="缓存">缓存</a><time datetime="2023-10-23T13:04:48.005Z" title="Created 2023-10-23 21:04:48">2023-10-23</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By John Doe</div><div class="framework-info"><span>Framework </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>Theme </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="Read Mode"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="Toggle Between Light And Dark Mode"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="Toggle between Single-column and Double-column"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="Setting"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="Table Of Contents"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="Back To Top"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/zwt-life/js/utils.js"></script><script src="/zwt-life/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><div class="js-pjax"></div><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>